在循环中的第一行末尾添加单词列表

在循环中的第一行末尾添加单词列表

我有一个包含多个文件名称的列表:

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

使用mapfilesed

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

相关内容