我有一个包含多个文件名称的列表:
file1
file2
我想在每个文件的第一行末尾添加文件名,例如:
文件 1 第一行将是
> ATCGCCfile1
文件 2 第一行将是
> ATTTCCfile2
我现在的想法是创建一个带有文件名的变量 a :
a="file1 file2"
循环遍历文件并添加单词重新调用索引:
for i in $a; do cat $i | awk '{print $0"$i"}' > $i.extended_word.txt; done
但是在输出中awk '{print $0"$i"}'
不起作用,只给我 $i 而没有文件名,例如在第一个文件的情况下>ATCGCC$i
。
我究竟做错了什么?我也尝试过括号(awk '{print $0"${i}"}'
)但没有成功。
答案1
要存储列表,您需要一个数组:
a=(
file1
file2
'other file with spaces'
$'even with\nnewlines'
)
awk -- '
FNR == 1 {
close(out)
$0 = $0 FILENAME
out = FILENAME".extended_word.txt"
}
{print > out}' "${a[@]}"
请注意,如果文件名包含=
字符,您需要确保剩下的=
不是有效的awk
变量。例如,如果您有一个file=1
文件,请将其设为./file=1
.
对于 GNU awk
,解决方法是编写它:
gawk -e '
FNR == 1 {$0 = $0 FILENAME}
{print > FILENAME ".extended_word.txt"}
' -E /dev/null "${a[@]}"
即使对于路径中带有 的文件也适用=
,但不幸的是仍然不适用于名为-
.
答案2
假设所有文件都位于同一目录中,并且列表位于一个文件中:
文件.txt
file1
file2
使用mapfile
和sed
:
mapfile -t files < files.txt
for f in "${files[@]}"; do
if [ ! -f "$f" ]; then
echo "File '$f' does not exists."
continue
fi
sed "1s;.*;&$f;" "$f"
# With option '-i' the file will be written
# sed -i "1s;.*;&$f;" "$f"
done