我使用以下 sed 命令删除除包含模式的匹配之外的所有行:
sed '/orders="Green\|orders="Orange\|orders="Blue/!d'
这可行,但如何使它更短以便orders="
只使用一次?
sed '/orders="["Green","Orange","Blue"]/!d'
类似这样的内容会匹配括号之间的任意字符,但会忽略整个单词。
我使用以下 sed 命令删除除包含模式的匹配之外的所有行:
sed '/orders="Green\|orders="Orange\|orders="Blue/!d'
这可行,但如何使它更短以便orders="
只使用一次?
sed '/orders="["Green","Orange","Blue"]/!d'
类似这样的内容会匹配括号之间的任意字符,但会忽略整个单词。
我正在使用带有一些内联 Python 的 Bash 脚本来读取 JSON API。我取出一小部分输出并将其转储到临时文件中。我知道临时文件存在,因为我能够head
对其运行操作。但是,当需要实际迭代文件中的行时,我收到如下错误read: /tmp/temporary_tag_storage.H9hEH6': not a valid identifier
以下是我的脚本的完整相关部分:
#!/usr/bin/env bash
getTagByNumber () {
SOMETHING=$(curl -s 'https://localhost:8000/api/tagstubs' | \
python3 -c "import sys, json; print(json.load(sys.stdin)[$1]['tag'])")
echo "$SOMETHING" >&3
}
TAGNUMBER=0;
tmpfile=$(mktemp /tmp/temporary_tag_storage.XXXXXX)
# create file descriptor 3 for writing to a temporary file so that
# echo ... >&3 writes to that file
exec 3>"$tmpfile"
# create file descriptor 4 for reading from the same file so that
# the file seek positions for reading and writing can be different
exec 4<"$tmpfile"
while [ $TAGNUMBER -lt 5 ]
do
getTagByNumber $TAGNUMBER $TAGS
TAGNUMBER=$(( $TAGNUMBER + 1 ))
done
#This works, dutifully spitting out five lines of text.
head -n $TAGNUMBER <&4
#So why does this give me "not a valid identifier"?
while read $tmpfile; do
echo "$p"
done
#rm "$tmpfile"
...输出如下:
politics
sports
religion
film
television
./createtags.sh: line 83: read: `/tmp/temporary_tag_storage.H9hEH6': not a valid identifier
如您所见,第一次尝试读取标签成功,输出了一堆主题名称。这就是为什么我对第二次while
循环失败感到困惑。
我尝试$tmpfile
在第二个循环的定义中用双引号括住变量名while
,但这似乎没有帮助。
有谁知道我做错了什么?
我们使用一个脚本将 bash 命令打印到文件中,然后在 HPC 系统上运行。它应该运行一个包含由空格分隔的地理坐标的大型文本文件,并从该文件中提取特定区域(例如,提取 x 坐标介于 xmin 和 xmax 之间且 y 坐标介于 ymin 和 ymax 之间的所有行)。
理想情况下,我希望像这样使用 awk 来实现这一点(因为我现在没有电脑,所以只能凭记忆来):
awk -v xmin=-13000 -v xmax=13000 -v ymin=-500 -v ymax=500 -F ' ' {if ($1 > xmin && $1 < xmin && $2 > ymin && $2 < ymin) print $1 $2} $infile > $outfile
这可能执行得很好。但是,正如标题所示,我们间接为 25 个区域保存了此行,每个区域都有自己的 xmin、xmax 等。之后还有更多操作(使用 GMT 调用等)。这里有一个小片段:
xmin=-13000
xmax=13000
ymin=-500
ymax=500
infile=./full_file.txt
outfile=./filtered_file.yxy
srcfile=./region_1.txt
echo """awk -v xmin=$xmin -v xmax=$xmax -v ymin=$ymin -v ymax=$ymax -F ' ' {if ($1 > $xmin && $1 < $xmin && $2 > $ymin && $2 < $ymin) print $1 $2} $infile > $outfile""" >> $srcfile
显然,由于变量扩展,这会在运行时引发错误。我尝试过转义 awk 列标识符,但无济于事,或者没有正确理解模式。有人能告诉我一个允许我们保留间接方法的解决方案吗?
我正在使用shdoc为我的 bash 函数生成 markdown 文件;但是,我还想将相关的 bash 函数主体以及该主体中的注释附加到由 生成的 markdown 文件中shdoc
。如何打印 bash 函数主体,同时还包括函数主体中的注释?
举一个简单的例子,假设我的所有 bash 文件都包含在一个名为的目录中src
,并且所有这些文件都以 结尾.sh
。文件中的以下函数src/foo.sh
# @description A function that does something
foo() {
# oh wow, a comment
echo "something cool"
}
现在,如果我想获取没有注释的函数主体,我可以轻松地做到这一点,declare -f
如下所示,在名为的文件中src/doc.sh
:
# assuming you are in the `src` dir and both .sh files are executable
. foo.sh
foo_doc=$(declare -f foo)
echo "$foo_doc"
但问题是foo_doc
只有函数体,因为echo "$foo_doc"
foo ()
{
echo "something cool"
}
并且没有任何注释。因此,如果我将此信息附加到由 生成的 markdown 中shdoc
,它就不是源代码的理想文档。
我认为一种方法是使用sed
来确定与感兴趣的函数相对应的行(我的 bash 函数由 和 “分隔” {
,}
但根据评论我理解还有其他方法可以声明有效的 bash 函数),然后我可以使用来仅获取这里sed
完成的那些行。
-
我想使用空格作为分隔符来拆分包含第一个字符的字符串。但以下代码似乎不起作用。如果我删除该-
字符,它就会正确拆分。这是脚本
#!/bin/bash
string="-e -/a/b/c/d"
arr=($string)
arrLen=${#arr[@]}
echo $arrLen
echo ${arr[0]} #prints empty
if [ $arrLen = 2 ] && [ ${arr[0]} = "-e" ]; then #this condition gets passed surprisingly
echo "Hi ${arr[1]}"
fi
输出
2
Hi -a/b/c/d
鉴于我拥有的字符串是基于来自不同文件的 ASV(如键),我想返回具有最高值的 ASV 匹配项。但是,有时会出现平局,这可能会带来问题,因此我想返回一条消息。
排序后,我能够返回具有最高值的行,但我不知道如何正确解释平局。
以下是我的文件的片段file.txt
:
ASV,Kingdom,Phylum,Class,Order,Family,Genus,Species,Hits
29ec61e470705074f483368a70ad18a7,Bacteria,???,???,???,???,???,uncultured bacterium,5
29ec61e470705074f483368a70ad18a7,Bacteria,Chloroflexota,Anaerolineae,???,???,???,uncultured Anaerolineae,2
29ec61e470705074f483368a70ad18a7,Bacteria,Chloroflexota,???,???,???,???,uncultured Chloroflexota,1
29ec61e470705074f483368a70ad18a7,Bacteria,???,???,???,???,???,unidentified marine,1
29ec61e470705074f483368a70ad18a7,Bacteria,Chloroflexota,Chloroflexia,Chloroflexales,Chloroflexaceae,Chloroflexus,uncultured Chloroflexus,1
74627d6dc445e8b5f46a787cf81c4294,Bacteria,Pseudomonadota,Gammaproteobacteria,Legionellales,Legionellaceae,???,uncultured Legionellaceae,2
74627d6dc445e8b5f46a787cf81c4294,Bacteria,???,???,???,???,???,uncultured bacterium,5
74627d6dc445e8b5f46a787cf81c4294,Bacteria,Pseudomonadota,Gammaproteobacteria,Legionellales,Legionellaceae,Legionella,Legionella sp.,3
55b1bec5f8dbe1b58007aee7ede9bae3,Bacteria,Bacteroidota,Cytophagia,Cytophagales,Cytophagaceae,Spirosoma,Spirosoma utsteinense,2
55b1bec5f8dbe1b58007aee7ede9bae3,Bacteria,???,???,???,???,???,uncultured bacterium,2
55b1bec5f8dbe1b58007aee7ede9bae3,Bacteria,Bacteroidota,Cytophagia,Cytophagales,Cytophagaceae,Spirosoma,Spirosoma sp.,2
55b1bec5f8dbe1b58007aee7ede9bae3,Bacteria,Bacteroidota,Cytophagia,Cytophagales,Cytophagaceae,Spirosoma,Spirosoma rigui,6
8964b7d833654ceedbdb6f6f25fb7d6a,Bacteria,???,???,???,???,???,uncultured bacterium,8
8964b7d833654ceedbdb6f6f25fb7d6a,Bacteria,Bacillota,Tissierellia,Tissierellales,Peptoniphilaceae,Finegoldia,Finegoldia magna,1
8964b7d833654ceedbdb6f6f25fb7d6a,???,???,???,???,???,???,uncultured organism,1
9966f0e6e452c31de46d030bab01fdd9,Bacteria,Bacteroidota,Sphingobacteriia,Sphingobacteriales,???,???,uncultured Cytophagales,2
9966f0e6e452c31de46d030bab01fdd9,Bacteria,Bacteroidota,Cytophagia,Cytophagales,Cytophagaceae,Spirosoma,Spirosoma jeollabukense,2
9966f0e6e452c31de46d030bab01fdd9,Bacteria,Bacteroidota,Cytophagia,Cytophagales,Cytophagaceae,Spirosoma,Spirosoma migulaei,2
9966f0e6e452c31de46d030bab01fdd9,Bacteria,Bacteroidota,Cytophagia,Cytophagales,Cytophagaceae,Spirosoma,Spirosoma sp.,1
举个例子,搜索 ASV29ec61e470705074f483368a70ad18a7
并返回具有最高值(最后一列)的匹配很容易:
代码:
> grep 29ec61e470705074f483368a70ad18a7 file.txt | sort -t, -nr -k9 | head -n1
# Output
29ec61e470705074f483368a70ad18a7,Bacteria,???,???,???,???,???,uncultured bacterium,5
但是如果我正在搜索诸如的 ASV 9966f0e6e452c31de46d030bab01fdd9
,我需要它以某种方式返回或知道可以返回三行(其中 3 行的值为 2)并输出一条消息:
理想输出:
> grep 9966f0e6e452c31de46d030bab01fdd9 file.txt | does something
# Output
CHECK: There are 3 lines tied for top.
我有一个命令ts
,它将一个命令和该命令的参数作为其参数。我希望制表符补全能够“做正确的事情”,即:
例如,当我输入时,ts foo<tab>
bash 应该尝试自动完成并查找以 开头的任何命令foo
。我这样做是这样的:
complete -F __ts_bash_completions ts
__ts_bash_completions () {
COMPREPLY=();
# if there's only one word on the command line
if [ "$COMP_CWORD" -eq 1 ]; then
COMPREPLY=($(compgen -c -- "${COMP_WORDS[COMP_CWORD]}"));
一旦它有了完整的命令名称,我希望后续参数的制表符补全使用第一个参数的制表符补全语义。如果没有为第一个参数定义补全函数,我也可以正常工作。继续上面的操作,这有效:
# otherwise ...
else
local command_completion_function="$(complete -p ${COMP_WORDS[1]} 2>/dev/null|sed 's/.*-F \([^ ]*\) .*/\1/')"
if [ -z "$command_completion_function" ]; then
COMPREPLY=($(compgen -W "$(ls)" -- "${COMP_WORDS[COMP_CWORD]}"));
但我纠结的是最后一个要求,即如果有可用的完成函数,就应该使用它,但我就是无法让这个该死的东西工作。我看过这个问题和它的答案,并试图将其概括如下。再次继续上面的内容:
else
echo using $command_completion_function
echo COMP_CWORD="$COMP_CWORD"
echo COMP_LINE="$COMP_LINE"
echo COMP_WORDS="${COMP_WORDS[*]}"
COMP_CWORD=$(( $COMP_CWORD - 1 ))
COMP_LINE=$(echo $COMP_LINE|sed "s/^${COMP_WORDS[0]} //")
unset COMP_WORDS[0]
echo COMP_CWORD="$COMP_CWORD"
echo COMP_LINE="$COMP_LINE"
echo COMP_WORDS="${COMP_WORDS[*]}"
$command_completion_function
fi
fi
}
就我从各种变量来看一切看起来都正常,但有人能发现这个愚蠢的错误吗?echo
COMP_*
我有一个音频文件库,其组织方式如下Audio/ArtistName/AlbumName/TrackName.ext
。许多元数据都是不正确的,我想使用FFmpeg 元数据一次性更正所有文件。
我发现这篇文章可以在子文件夹内的文件上执行命令。但是,我仍然需要子文件夹的名称ArtistName
和子文件夹内的文件,AlbumName
才能在每个音频文件上执行命令:
ffmpeg -i inputfile -metadata artist="Subfolder Artist Name" -metadata album="Subfolder Album Name" outputfile
如何根据文件所在子文件夹的名称编辑文件元数据?
编辑:我正尝试在 Linux CLI 或 Bash 脚本中执行此操作。我尝试遍历文件夹(艺术家),然后遍历其中的子文件夹(专辑),然后循环遍历文件并根据艺术家文件夹和专辑子文件夹的名称值运行命令。我曾尝试过循环遍历文件夹,但它不适用于子文件夹,无法对子文件夹中的文件执行命令。我能够返回艺术家和专辑名称,但我仍然无法获取曲目名称。cd
进入艺术家文件夹有效,但进入专辑文件夹无效
for artist in /tank/music/*/
do
art= basename "${artist}"
cd "${artist}"
for album in ./*/
do
alb= basename "${album}"
cd "${album}"
for track in ./*/
do
echo "${art}"
echo "${alb}"
echo "${track}"
done
done
done
如何使用cat
带有此处文档的 shell 脚本命令来创建文件”
#!/bin/bash
create_file () {
cat > a.txt << EOF
0 abc def
ghi jkl mno
pqrs tuv wxyz
EOF
}
create_file
错误
Syntax error: end of file unexpected (expecting "}")
我正在尝试过滤 Github 中的 Pull 请求,如果有特定的 PR,我们不需要为此创建 PR,我已在下面包含了代码,但它显示错误line 61: syntax error: unexpected end of file
通常 PR 名称应该是这样的 = 检查资源中的漂移:$RESOURCE
echo "Checking if a pull request for '$RESOURCE' already exists"
existing_pr=$(curl -s -H "Authorization: Bearer $(pat-token)" \
https://github.mytab.com/api/v3/repos/rep/rep-infra/pulls?state=open&head=drift-rep-${RESOURCE} \
| jq '.[] | select(.title | test("Checking drift in the resource: '"$RESOURCE"'"))')
if [ -n "$existing_pr" ]; then
echo "Pull request already exists for '$RESOURCE'. Skipping PR creation."
else
echo "Creating Pull Request now"
逻辑上有什么错误吗?