GNU/Linux >> Linux の 問題 >  >> Linux

Bash でファイルの内容をループする

cat peptides.txt | while read line 
do
   # do something with $line here
done

ワンライナーバリアント:

cat peptides.txt | while read line; do something_with_$line_here; done

これらのオプションは、末尾に改行がない場合、ファイルの最後の行をスキップします。

これは次の方法で回避できます:

cat peptides.txt | while read line || [[ -n $line ]];
do
   # do something with $line here
done

オプション 1a: While ループ:一度に 1 行ずつ:入力リダイレクト

#!/bin/bash
filename='peptides.txt'
echo Start
while read p; do 
    echo "$p"
done < "$filename"

オプション 1b: While ループ:一度に 1 行ずつ:
ファイル記述子 (この場合はファイル記述子 #4) から読み取ったファイルを開きます。

#!/bin/bash
filename='peptides.txt'
exec 4<"$filename"
echo Start
while read -u4 p ; do
    echo "$p"
done

これは他の回答よりも優れているわけではありませんが、スペースのないファイルで仕事を成し遂げるもう1つの方法です(コメントを参照)。別のスクリプト ファイルを使用する追加の手順を使用せずに、テキスト ファイル内のリストを掘り下げるには、ワンライナーが必要になることがよくあります。

for word in $(cat peptides.txt); do echo $word; done

この形式により、すべてを 1 つのコマンドラインに入れることができます。 「echo $word」部分を任意に変更すると、セミコロンで区切られた複数のコマンドを発行できます。次の例では、ファイルの内容を、作成した他の 2 つのスクリプトへの引数として使用しています。

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done

または、これをストリーム エディターのように使用する (sed を学習する) 場合は、次のように出力を別のファイルにダンプできます。

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done > outfile.txt

上記のようにこれらを使用しました。これは、1 行に 1 語で作成したテキスト ファイルを使用したためです。 (コメントを参照してください) 単語/行を分割したくないスペースがある場合、少し見苦しくなりますが、同じコマンドは次のように機能します:

OLDIFS=$IFS; IFS=$'\n'; for line in $(cat peptides.txt); do cmd_a.sh $line; cmd_b.py $line; done > outfile.txt; IFS=$OLDIFS

これは、スペースではなく改行のみで分割するようにシェルに指示し、環境を以前の状態に戻します。ただし、この時点で、すべてを 1 行にまとめるのではなく、すべてをシェル スクリプトに入れることを検討することをお勧めします。

幸運を祈ります!


1 つの方法は次のとおりです。

while read p; do
  echo "$p"
done <peptides.txt

コメントで指摘されているように、これには、先​​頭の空白のトリミング、バックスラッシュ シーケンスの解釈、および最後の改行がない場合の最後の行のスキップという副作用があります。これらが懸念事項である場合は、次のことを行うことができます:

while IFS="" read -r p || [ -n "$p" ]
do
  printf '%s\n' "$p"
done < peptides.txt

例外的に、ループ本体が標準入力から読み取る可能性がある場合は、別のファイル記述子を使用してファイルを開くことができます:

while read -u 10 p; do
  ...
done 10<peptides.txt

ここで、10 は単なる任意の数です (0、1、2 とは異なります)。


Linux
  1. Linuxターミナルでファイルの名前を変更します

  2. すべての端末出力をファイルに保存しますか?

  3. Dconfデータベースファイルのバックアップの内容を表示する方法は?

  1. Bashで、最初のX行をスキップしてファイルを印刷します

  2. Bash でパス変数の要素をループする

  3. ファイルを gunzip して .gz ファイルを保持するにはどうすればよいですか?

  1. 名前にスペースが含まれるファイルをループする??

  2. Bashスクリプトがエイリアスを認識しないのはなぜですか?

  3. ファイルの内容をコマンド「echo」にリダイレクトしますか?