🦔

【Linux 】備忘のためのファイル・文字列編集コマンドまとめ

2021/02/23に公開

記事について


・「一度コマンドを学んだけど書き方どうだったっけ?」を思い出すための記事です。
・コマンド、またコマンドのオプションを全て網羅するものではないことをご理解ください。
・新しい表現を学んだら書き足していくつもりです。

ファイル文字列編集コマンドまとめ


tac 逆順出力
tac file.txt #逆順出力 ※最終行から出力
sed 置換 削除
sed 's/one/ONE/' file.txt #各行の最初のoneをONEに置き換え ※「各行の最初の」は以降省略
sed 's/\/usr\/local/\/common/' file.txt #/usr/localを/commonに置き換え
sed 's:/user/local:/common:' file.txt #上が読みづらいため書き換え版  デリミタに:を利用する
sed -e 's/\bone\b/ONE/' file.txt #単語oneのみをONEに変換する oneceは変換しない \bは単語の先頭、末尾を表す
sed 's/one/ONE/ig' file.txt #全てのoneをONEに置き換え(大小区別しない)
sed 's/\bone\b/{&}/ig' file.txt #全てのoneを{one}に置き換え Oneは{One}に置き換え &は置換え対象の文字列を引き継ぐ
sed 's:\([0-9]\+\):aaa:' #連続した数字123等をaaaに置換え
sed -r 's:([0-9]+):aaa:' #上と同じ(-r はエスケープ\を使わずに表現するためのもの)
grep 検索
grep "this" file.txt #file.txtのthisを含む行を出力
grep '^this' file.txt #thisが行頭にある行を出力
grep 'this$' file.txt #thisが行末尾にある行を出力
grep -c "this" file.txt #thisを含む行数を出力
grep -oP '名前="'[亜-熙ぁ-ん]*'"' file.txt #「名前="日本語の文字列"」文字列を抜き出す。行ではなく、文字列単位で抜き出し、文字列ごとに1行ずつ出力される。 -o;文字列抜き出し -P;Perlの正規表現を使用できるようになる[a-z]など
grep -P -o '(?<=名前=\")[^\"]*(?=")' file.txt #「名前="日本語の文字列"」文字列を抜き出す。
grep -n "this" file.txt #thisを含む行番号と行を出力
grep -w "the" file.txt #theを含む行を出力(完全一致:thenは出力しない)
grep -i "this" file.txt #thisを含む行を出力(大文字小文字を区別しない)
grep -v "this" file.txt #thisを含む行以外を出力
grep "this" file*.txt #file1.txt,file2.txt...のthisを含む行を出力
grep -i -e "the" -e "that" file.txt #theとthatを含む行を出力(大小区別なし)
grep -A 2 "中央" file.txt #"中央"の行と、"中央"を含む行の後の行から2行を出力 After
grep -B 2 "中央" file.txt #"中央"の行と、"中央"を含む行の前の行から2行を出力 Before
grep -C 2 "中央" file.txt #"中央"の行と、"中央"を含む行の前後の行から2行を出力 Around 前2行、後2行
grep -e '\([0-9]\)\1' file.txt #連続した数字を持つ行を出力する  11とか22とか99
#上記コマンドは後方参照 ([0-9])は任意の数字を検出し、後方で参照するための記述。\1で参照する。
#例えば上記のコマンドは"1134"を処理するとき、([0-9])で1を検出し、\1に1を参照させる。つまり([0-9])\1で11になる。 説明になってるか微妙。。

○先読みあと読み grep -oP
grepの-oオプションと-Pオプションの組み合わせが便利

head 先頭から出力
head -5 file.txt #先頭から5行出力
head -n 5 file.txt #先頭から5行出力
head -c 20 file.txt #先頭から20文字出力
head -10 file.txt | tail -5 #6~10行目を出力
tail 末尾から出力
tail -20 file.txt #最終行から20行出力
tail -c 20 file.txt #最終行から20文字出力
paste ファイルの結合 行と列を入れ替える
paste 元ファイル1 元ファイル…
cat file1.txt
1
2
3
cat file2.txt
apple
music

paste file1.txt file2.txt #file1とfile2を行方向で結合
1     apple
2     music
3
paste -s file1.txt file2.txt #file1とfile2を列方向で結合
1        2       3
apple    music     
paste -s file1.txt
1        2       3
paste -d ',' - - file1.txt #file1.txtをカンマ区切りで2列ずつ表示 [- -]は-sと同じように横並べする意味合いがある ※-sオプションは併用しない
1,2
3

#以下コマンドのみ
paste -d ',' file1.txt file2.txt #file1とfile2を行方向で結合(カンマ区切り)
sort 並べ替え
sort file.txt #辞書式順序で並べる
sort file.txt #辞書式順序で並べる(重複行を省く)
sort -f file.txt #辞書式順序で並べる(大文字を考慮しない)
sort -n file.txt #数字を昇順で並べる
sort -r -n file.txt #数字を降順で並べる
sort -k 2 -t ',' file.txt #,で区切られたレコードの2列目以降で並べる ※“以降“に注意
sort -k 2,2 -t$'\t' file.txt #tabで区切られたレコードの2列目で並べる
sort -k 2,4 -t$'\t' file.txt #tabで区切られたレコードの2〜4列目で並べる(2,3,4の順で優先
sort -t$'\t' -k2rn file.txt #こんな感じでオプションをまとめてもOK
uniq ユニーク行/重複行出力 重複行削除

uniqコマンドはソートされたファイルにのみ機能する点に注意
実際には「sort file.txt | uniq」のようにsortコマンド結果をパイプでつないで処理することが多い

uniq file.txt #重複行を省いて出力(重複行を1つにまとめて出力)
uniq file.txt file2.txt #file.txtの重複行を省いた結果をfile2.txtに保存
uniq -c file.txt #重複した行数と行を出力 [      3 aaa]のように出力される
uniq -c | tr -s ' ' | cut -c 2- #重複した行数と行を出力 [3 aaa]のように出力される
uniq -i file.txt #大文字小文字を無視して重複行を省いて出力 ※出力は小文字になる
uniq -u file.txt #ユニーク行を出力
uniq -d file.txt #重複行を出力
tr 文字の置換 削除
cat file.txt | tr 1 2 #1を2に変換
cat file.txt |tr -d '[a-z]' #小文字を削除
cat file.txt |tr -d '\t' #tabを削除
cat file.txt | tr -s ' ' #連続したスペースを単一のスペースに変換
tr abc 123 file.txt #aを1に、bを2に、cを3に置換
cut 切り出す(○文字目、○列目を)
cut [オプション] [ファイル]
cut -b 2-4 file.txt #2~4バイトまでを抜き出す
cut -c 3 file.txt #3文字目を抜き出す
cut -c 2,4 file.txt #2,4文字目を抜き出す
cut -c 3- file.txt #3文字以降を抜き出す
cut -d , -f -3 file.txt #1~3フィールド目を抜き出す(区切り文字,) ※区切り文字がない場合は先頭の文字列が表示される。
cut -s -d , -f -3 file.txt #1~3フィールド目を抜き出す(区切り文字,) ※区切り文字がない場合は何も表示されない。
cut -f -3 file.txt #1~3フィールド目を抜き出す(区切り文字タブ) ※デフォルトの区切り文字はタブなので-dは省略
printf 出力文字列編集
printf format [argument]...
printf "%.3f" 2.5
2.500

echo は改行を付与する。printf は改行したいときに自分で改行を入れる必要がある。

○formatのオプション指定は以下参照(C言語ですが、これが分かりやすい)
printf - フォーマット形式で文字列を表示する

awk ファイルになんやかんやして出力(やり方次第で多分なんでもできる)
awk '条件文{実行文}' ファイル名
awk '{ print }' file.txt #file.txtを出力 aa bb cc
awk '{ print $0 }' file.txt #file.txtを出力 aa bb cc
awk '{ print $1 }' file.txt #file.txtの1列目を出力
awk '{ print $1,$3 }' file.txt #1,3列目を出力 aa cc
awk '{ print $1.$3 }' file.txt #1,3列目を連結して出力 aacc
awk '{ print $NF }' file.txt #最終列を出力 cc
awk '/test/ { print }' file.txt #testを含む文字列を出力
awk '/[a-z]/ { print }' file.txt #小文字を含む文字列を出力
awk 'NF != 4 { print }' file.txt #列の数が4でない行を出力する NF=列の数
awk '{ print $1,$2*2.0 }' file.txt #1列目と2列目を2倍した値を出力
awk 'BEGIN { print "==BEGIN==" } { print $0} END { print "==END==" }' file.txt #BEGIN=開始処理宣言で、今回は{print "==BEGIN=="}を処理 END=終了処理宣言

#awk条件文 2,3,4列目が全て50点以上なら「1列目: Pass」それ以外なら「1列目: Fail」
awk '{
    if($2 >= 50 && $3 >= 50 && $4 >= 50){ #条件文の中身は{}でくくる
        print $1" : Pass"
    } else{
        print $1" : Fail"
    }
}' file.txt

#awk条件文 2,3,4列目の平均が80以上ならA、60以上ならB、その他はFAIL
awk '{ 
    avg=($2+$3+$4)/3 
    if( avg >= 80) #awkの中では数字の計算ができる(しかも-geとか使わない)
        print $0" : A"; #{}を使わない書き方の場合は;をつける
    else if(avg >=60)
        print $0" : B";
    else
        print $0" : FAIL"; #fiは必要ない
}'

#awk条件文
awk '{
    for(i=0; i < 10; i++){
        printf i;
    }
}'

Discussion