Bash命令根据我传递的参数读取一行-执行基于列的查找
我有一个links.txt文件:Bash命令根据我传递的参数读取一行-执行基于列的查找,bash,unix,awk,sed,lookup,Bash,Unix,Awk,Sed,Lookup,我有一个links.txt文件: 1 a.sh 3 b.sh 6 c.sh 4 d.sh 因此,如果我将1,4作为参数传递给另一个文件(master.sh),a.sh和d.sh应该存储在一个变量中 循环遍历每个参数,并在链接文件中对其进行greps。结果通过管道传输到cut中,在这里我们将分隔符指定为带-d标志的空格,将字段号指定为带-f标志的2。最后,它被附加到名为files的数组中 links="links.txt" files=() for arg in $@; do file
1 a.sh
3 b.sh
6 c.sh
4 d.sh
因此,如果我将1,4作为参数传递给另一个文件(master.sh),a.sh和d.sh应该存储在一个变量中 循环遍历每个参数,并在链接文件中对其进行greps。结果通过管道传输到cut中,在这里我们将分隔符指定为带-d标志的空格,将字段号指定为带-f标志的2。最后,它被附加到名为files的数组中
links="links.txt"
files=()
for arg in $@; do
files=("${files[@]}" `grep "^$arg" "$links" | cut -d" " -f2`)
done;
echo ${files[@]}
用法:
$ ./master.sh 1 4
a.sh d.sh
$ ./master.sh 1 4
a.sh d.sh
编辑:
正如mklement0所指出的,上面的解决方案每个参数读取一次文件。下面的代码首先构建模式,然后只读取文件一次
links="links.txt"
pattern="^$1\s"
for arg in ${@:2}; do
pattern+="|^$arg\s"
done
files=$(grep -E "$pattern" "$links" | cut -d" " -f2)
echo ${files[@]}
用法:
$ ./master.sh 1 4
a.sh d.sh
$ ./master.sh 1 4
a.sh d.sh
这将循环遍历每个参数,并在链接文件中对其进行greps。结果通过管道传输到cut中,在这里我们将分隔符指定为带-d标志的空格,将字段号指定为带-f标志的2。最后,它被附加到名为files的数组中
links="links.txt"
files=()
for arg in $@; do
files=("${files[@]}" `grep "^$arg" "$links" | cut -d" " -f2`)
done;
echo ${files[@]}
用法:
$ ./master.sh 1 4
a.sh d.sh
$ ./master.sh 1 4
a.sh d.sh
编辑:
正如mklement0所指出的,上面的解决方案每个参数读取一次文件。下面的代码首先构建模式,然后只读取文件一次
links="links.txt"
pattern="^$1\s"
for arg in ${@:2}; do
pattern+="|^$arg\s"
done
files=$(grep -E "$pattern" "$links" | cut -d" " -f2)
echo ${files[@]}
用法:
$ ./master.sh 1 4
a.sh d.sh
$ ./master.sh 1 4
a.sh d.sh
sed'3!d'
将打印第三行,但不会打印以3开头的行。为此,您需要sed'/^3/!d'
。问题是你不能将它们组合成更多的行,因为这意味着“删除所有不以3开头的行”,这意味着所有其他行都将丢失。因此,请改用sed-n'/^3/p'
,即默认情况下不打印,并告诉sed要打印哪些行,而不是要删除哪些行
您可以在参数上循环并从中创建一个sed脚本,用于打印行,然后使用以下输出运行sed
:
#!/bin/bash
file=$1
shift
for id in "$@" ; do
echo "/^$id /p"
done | sed -nf- "$file"
以script.sh文件名3 4
运行
如果要从输出中删除id,可以使用
cut -f2 -d' '
或者,您可以修改生成的sed脚本来完成这项工作
echo "/^$id /s/.* //p"
i、 e.仅当替换成功时才打印。sed'3!d'
将打印第三行,但不会打印以3开头的行。为此,您需要sed'/^3/!d'
。问题是你不能将它们组合成更多的行,因为这意味着“删除所有不以3开头的行”,这意味着所有其他行都将丢失。因此,请改用sed-n'/^3/p'
,即默认情况下不打印,并告诉sed要打印哪些行,而不是要删除哪些行
您可以在参数上循环并从中创建一个sed脚本,用于打印行,然后使用以下输出运行sed
:
#!/bin/bash
file=$1
shift
for id in "$@" ; do
echo "/^$id /p"
done | sed -nf- "$file"
以script.sh文件名3 4
运行
如果要从输出中删除id,可以使用
cut -f2 -d' '
或者,您可以修改生成的sed脚本来完成这项工作
echo "/^$id /s/.* //p"
i、 e.仅在替换成功时打印。以下awk
解决方案:
- 保留参数顺序;也就是说,结果反映了指定查找值的顺序(与查找值在文件中出现的顺序相反)
- 如果这并不重要(即,如果可以接受按文件顺序输出结果),则可以将下面的
readarray
技术与这一行程序结合使用,这是:
grep-f以下awk
解决方案:
- 保留参数顺序;也就是说,结果反映了指定查找值的顺序(与查找值在文件中出现的顺序相反)
- 如果这并不重要(即,如果可以接受按文件顺序输出结果),则可以将下面的
readarray
技术与这一行程序结合使用,这是:
grep-f这里是grep和cut的另一个示例:
#!/bin/bash
for line in $(grep "$1\|$2" links.txt|cut -d' ' -f2)
do
echo $line
done
用法示例:
./master.sh 1 4
a.sh
d.sh
下面是grep和cut的另一个示例:
#!/bin/bash
for line in $(grep "$1\|$2" links.txt|cut -d' ' -f2)
do
echo $line
done
用法示例:
./master.sh 1 4
a.sh
d.sh
为什么不存储这些值并随意调用它们:
items=()
while read -r num file
do
items[num]="$file"
done<links.txt
for arg
do
echo "${items[arg]}"
done
items=()
读取-r num文件时
做
items[num]=“$file”
完成为什么不存储值并随意调用它们:
items=()
while read -r num file
do
items[num]="$file"
done<links.txt
for arg
do
echo "${items[arg]}"
done
items=()
读取-r num文件时
做
items[num]=“$file”
完成您尝试了什么?请发布您的第一次尝试。LB是换行cat文件|,同时读取line
LBdo
。它遍历文件的所有行,但我希望根据参数读取该行。sed'3!d'links.txt
这给了我文件的第三行注意,这个问题没有指定结果是否必须反映参数顺序,或者是否可以按照文件中出现查找数字的顺序返回结果。例如,参数列表61
必须导致c.sh
和a.sh
(按该顺序),或者返回a.sh
在c.sh
之前是否可以,因为ID1
恰好位于文件中6
之前?我对现有答案进行了标记,以澄清它们实施的两种解决方案中的哪一种。您尝试了什么?请发布您第一次尝试的内容。LB是换行cat file;,同时读取line
LBdo
。它遍历文件的所有行,但我希望根据参数读取该行。sed'3!d'links.txt
这给了我文件的第三行注意,这个问题没有指定结果是否必须反映参数顺序,或者是否可以按照文件中出现查找数字的顺序返回结果。例如,参数列表61
必须导致c.sh
和a.sh
(按该顺序),或者返回a.sh
在c.sh
之前是否可以,因为ID1
恰好位于文件中6
之前?我已经标记了现有的答案,以澄清他们实施的两个解决方案中的哪一个。嗨,谢谢@choroba。当我通过3 4时,其显示3 b.sh
和4