【ちょいと便利な】シェルスクリプトワンライナー特集【一行完結】

ワンライナー

ワンライナー(英:one liner)とは
華麗な職人技によって処理を1行に全部詰め込んだ「1行ですべてが完結しているプログラムソース」のこと。

find

現在のディレクトリ内のすべてのサブディレクトリ/ファイルを一覧表示する

find .

現在のディレクトリの下にあるすべてのファイルを一覧表示する

find . -type f

現在のディレクトリの下にあるすべてのディレクトリを一覧表示する

find . -type d

現在のディレクトリの下にあるすべてのファイルを編集します (たとえば、‘www’ を ‘ww’ に置き換えます)。

find . -name '*.php' -exec sed -i 's/www/w/g' {} \;

ファイル名のみを検索して出力 (例: “mso”)

find mso*/ -name M* -printf "%f\n"

システム内の大きなファイルを見つける (例: >4G)

find / -type f -size +4G

サイズが 74 バイト未満のファイルを見つけて削除する

find . -name "*.mso" -size -74c -delete

空の (0 バイト) ファイルを見つける

find . -type f -empty

ディレクトリ内のすべてのファイルを再帰的にカウントする

find . -type f | wc -l

sort

列ごとにファイルを並べ替え、元の順序を維持する

sort -k3,3 -s

fold

指定された幅に収まるように各入力行を折り返す (例: 1 行あたり 4 つの整数)

echo "00110010101110001101" | fold -w4
# 0011
# 0010
# 1011
# 1000
# 1101

expand

タブをスペースに変換

expand filename

スペースをタブに変換

unexpand filename

wget

ページから全てをダウンロード

wget -r -l1 -H -t1 -nd -N -np -A mp3 -e robots=off http://example.com

ファイル名を指定してダウンロード(長い名前の場合)

wget -O filename "http://example.com"

wget ファイルをフォルダーに

wget -P /path/to/directory "http://example.com"

tr

末尾の改行をエコーしない

username=`echo -n "bashoneliner"`

ファイルを複数のファイルにコピー (例: fileA をファイル (BD) にコピー)

tee <fileA fileB fileC fileD >/dev/null

すべての非印刷文字を削除する

tr -dc '[:print:]' < filename

改行を削除

tr --delete '\n' <input.txt >output.txt

または

tr -d '\n' <input.txt >output.txt

改行を置換

tr '\n' ' ' <filename

大文字/小文字へ

tr /a-z/ /A-Z/

join

2 つのファイルをフィールドごとにタブで結合します (デフォルトでは両方のファイルの最初の列で結合し、デフォルトのセパレータはスペースです)

join -t '\t' fileA fileB

指定したフィールドを使用して結合します(例:fileAの3列目とfileBの5列目を結合)

join -1 3 -2 5 fileA fileB

paste

2 つ以上のファイルを列に結合/貼り付けます (例: fileA、fileB、fileC)

paste fileA fileB fileC

rev

逆文字列

echo 12345| rev

ファイルの最後の列を切り取って取得する

cat file|rev | cut -d/ -f1 | rev

最後の列を切り取る

cat filename|rev|cut -f1|rev

rename

すべてのファイルの名前を変更します (たとえば、すべての .gz ファイルから ABC を削除します)。

rename 's/ABC//' *.gz

すべてのファイルにファイル拡張子を追加します (例: .txt を追加)

rename s/$/.txt/ *

od

ファイルを 8 進数で表示します ( od を使用して 16 進数、10 進数などを表示することもできます)

od filename

10 進数から 2 進数 (例: 2 進数の 5 を取得)

D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
echo -e ${D2B[5]}
#00000101
echo -e ${D2B[255]}
#11111111

grep

空行をカウントする

cat filename.txt | grep -c "^$"

または、

cat filename.txt | grep "^$" | wc -l
ヒント
wc -lは、行数をカウントするwcコマンドです。
^$^ は行頭、 $は行末、いわゆる行頭と行末の間になにもない、それは空白行と意味します。
空白行をwc -lでカウントするということになります。

単語とマッチしない行を表示 (例: ‘bbo’)

cat filename.txt | grep -v bbo
ヒント
-vは、「ではない(マッチしない)」という意味になります。

一致する行番号を返す 検索文字列は(例: ‘bbo’)

cat filename.txt | grep -c bbo

特定の文字列で始まらない行を表示 (例: #)

cat filename.txt | grep -v '^#'
ヒント
^は行頭という意味です。

大文字と小文字を区別しない grep (例: ‘bbo’/‘BBO’/‘Bbo’)

cat filename.txt | grep -i "bbo"

マッチに色を付けます (例: ‘bbo’)!

cat filename.txt | grep --color bbo

sed

特定の行を出力 (例: 123 行目)

sed -n -e '123p'

行数を出力します (例: 10 行目から 33 行目)

cat filename | sed -n '10,33p'

n 行ごとに出力する

cat filename | sed -n '0~3p' 

奇数行ごとに出力

cat filename | sed -n '1~2p'

最初の行を含めて 3 行ごとに出力する

cat filename | sed -n '1p;0~3p'

置換 (例: A を B に置き換える)

cat filename | sed 's/A/B/g' 

ファイルを編集 (編集してファイルに保存) (例: ‘bbo’ で行を削除してファイルに保存)

sed -i "/bbo/d" filename

文字列を含む行を削除 (例: ‘bbo’)

cat filename | sed '/bbo/d'

1行目を削除

cat filename | sed 1d 

最初の100行(1行目から100行目まで)を削除

cat filename | sed 1,100d 

文字列を含む行を削除 (例: ‘bbo’)

cat filename | sed "/bbo/d"

空行の削除

cat filename | sed '/^\s*$/d'

または

cat filename | sed '/^$/d'

最後の行を削除

cat filename | sed '$d'

ファイルの末尾から最後の文字を削除

cat filename | sed -i '$ s/.$//'

先頭の空白とタブを削除

cat filename | sed -e 's/^[ \t]*//'

先頭の空白のみを削除

cat filename | sed 's/ *//'

末尾のカンマを削除

cat filename | sed 's/,$//g'

2行に間の改行を削除

currentLine
nextLine
$ cat newline.xt | sed ':a;N;$!ba;s/\n//g'
$ currentLinenextLine
$ 

ファイルの先頭に文字列を追加 (例: “[")

cat filename | sed -i '1s/^/[/'

特定の行番号に文字列を追加します (例: 1 行目と 3 行目に ‘something’ を追加)

cat filename | sed -e '1isomething' -e '3isomething'

ファイルの末尾に文字列を追加 (例: “]")

cat filename | sed '$s/$/]/'

最後に改行を追加

cat filaname | sed '$a\'

すべての行の先頭に文字列を追加します (例: ‘bbo’)

cat filename | sed -e 's/^/bbo/'

各行の末尾に文字列を追加します (例: “}")

cat filename | sed -e 's/$/\}\]/'

n 番目の文字ごとに \n を追加します (たとえば、4 番目の文字ごと)

cat filename | sed 's/.\{4\}/&\n/g'

最後に列を追加

for i in $(ls);do sed -i "s/$/\t$i/" $i;done

空白行の操作

空行1行を空行2行に増やす

sed G
awk '1;{print ""}'
awk 'BEGIN{ORS="\n\n"};1'

空行1行を空行3業に増やす

sed '/^$/d;G'
awk 'NF{print $0 "\n"}'

空行2行を空行1業に減らす

sed 'G;G'
awk '1;{print "\n"}'

sed ‘n;d’
一致するすべての行の上に空白行を挿入しますregex。

sed ‘/regex/{x;p;x;}’
に一致するすべての行の下に空白行を挿入しますregex。

sed ‘/regex/G’
正規表現に一致するすべての行の上下に空白行を挿入します。

sed ‘/regex/{x;p;x;G;}’
末尾に改行を追加します:

sed ‘$a'

awk

タブをフィールドセパレータとして設定

awk -F $'\t' 

タブ区切りとして出力 (フィールド区切りとしても)

awk -v OFS='\t'

変数を渡す

a=bbo;b=obb;
awk -v a="$a" -v b="$b" "$1==a && $10=b" filename

行番号と各行の文字数を出力する

awk '{print NR,length($0);}' filename

列数を出力

awk '{print NF}'

列の順序を逆にする

awk '{print $2, $1}'

列にコンマがあるかどうかを確認します (例: 列 $1)

awk '$1~/,/ {print}' 

列の先頭に文字列を追加します (たとえば、列 $3 に「chr」を追加します)。

awk 'BEGIN{OFS="\t"}$3="chr"$3'

文字列を含む行を削除 (例: ‘bbo’)

awk '!/bbo/' file

最後の列を削除

awk 'NF{NF-=1};1' file

ファイルのすべての番号を四捨五入 (例: 有効数字 2 桁)

awk '{while (match($0, /[0-9]+\[0-9]+/)){
    \printf "%s%.2f", substr($0,0,RSTART-1),substr($0,RSTART,RLENGTH)
    \$0=substr($0, RSTART+RLENGTH)
    \}
    \print
    \}'

すべての行に番号/インデックスを付ける

awk '{printf("%s\t%s\n",NR,$0)}'

ファイルの平均 (ファイルの各行には 1 つの数値のみが含まれます)

awk '{s+=$1}END{print s/NR}'

フィールドの先頭を文字列で表示 (Linux など)

awk '$1 ~ /^Linux/'

行を並べ替える (例: 1 40 35 12 23 –> 1 12 23 35 40)

awk ' {split( $0, a, "\t" ); asort( a ); for( i = 1; i <= length(a); i++ ) printf( "%s\t", a[i] ); printf( "\n" ); }'

前の行の値を減算します (column4 から最後の column5 を引いた値に等しい column6 を追加します)

awk '{$6 = $4 - prev5; prev5 = $5; print;}'

xargs

タブを区切り文字として設定 (デフォルト: スペース)

xargs -d\t

コマンドを実行する前にコマンドをプロンプトする

ls|xargs -L1 -p head

1 行に 3 項目を表示

echo 1 2 3 4 5 6| xargs -n 3
# 1 2 3
# 4 5 6

実行前のプロンプト

echo a b c |xargs -p -n 3

find の結果を rm する

find . -name "*.html"|xargs rm

ファイル名に空白が含まれるファイルを削除します (例: 「hello 2001」)

find . -name "*.c" -print0|xargs -0 rm -rf

ファイルをフォルダに移動

find . -name "*.bak" -print 0|xargs -0 -I {} mv {} ~/old

または、

find . -name "*.bak" -print 0|xargs -0 -I file mv file ~/old

最初の 100 番目のファイルをディレクトリ (例: d1) に移動します。

ls |head -100|xargs -I {} mv {} d1

並行処理

time echo {1..5} |xargs -n 1 -P 5 sleep

すべてのファイルを A から B にコピーします

find /dir/to/A -type f -name "*.py" -print 0| xargs -0 -r -I file cp -v -p file --target-directory=/path/to/B

ファイル名をファイルの最初の行に追加します

ls |sed 's/.txt//g'|xargs -n1 -I file sed -i -e '1 i\>file\' file.txt

すべてのファイルの行数を出力

ls |xargs -n1 wc -l

出力を 1 行にする

ls -l| xargs

すべてのファイルの行をカウントし、合計行もカウントします

ls|xargs wc -l

Xargs と grepを組み合わせる

cat grep_list |xargs -I{} grep {} filename

Xargs と sed (/etc ディレクトリの下のすべての古い IP アドレスを新しい IP アドレスに置き換えます)

grep -rl '192.168.1.111' /etc | xargs sed -i 's/192.168.1.111/192.168.2.111/g'

if

文字列一致の検出

if [[ "$c" == "read" ]]; then outputdir="seq"; else outputdir="write" ; fi

myfile に文字列 ‘test’ が含まれているかどうかを確認

``` bah
if grep -q hello myfile; then echo -e "file contains the string!" ; fi

変数がnull であるかを確認

myvariable="";if [ ! -s "myvariable" ]; then echo -e "variable is null!" ; fi

該当のファイルが存在するかを確認

if [ -e 'filename' ];then echo -e "file exists!"; fi

ファイルに加えてシンボリックリンクの存在も確認

if [ -e myfile ] || [ -L myfile ];then echo -e "file exists!"; fi

xの値が5以上かどうかを確認

if [ "$x" -ge 5 ]; then echo -e "greater or equal than 5!" ; fi

bash版:xの値が5以上かどうかを確認

if ((x >= 5)); then echo -e "greater or equal than 5!" ; fi

(( )) を使う

j=3;u=1;if ((j==u+2)); then echo -e "j==u+2";fi

[[ ]] を使う

age=25;if [[ $age -gt 21 ]]; then echo -e "forever 21" ; fi

for

ディレクトリ内のファイル名を出力

for i in $(ls); do echo file: $i;done

もしくは、

for i in *; do echo file: $i; done

myfile内に記載された名前を使ってディレクトリを作成

for dir in $(<myfile); do mkdir $dir; done

openssl

16 進数の MD5 チェックサム値を base64 エンコード形式に変換します。

openssl md5 -binary /path/to/file| base64
# NWbeOpeQbtuY0ATWuUeumw==

言語属性

アプリケーションが出力にデフォルト言語を使用することを強制します

export LC_ALL=C

# to revert:
unset LC_ALL

文字列を Base64 文字列としてエンコードする

echo test|base64
#dGVzdAo=

バッググラウンド処理

バックグラウンドで複数のコマンドを実行する

(sleep 2; sleep 3) &

# run parallelly
sleep 2 & sleep 3 &

CSV系

.xls を csv に変換

xls2csv filename

ステータス処理

別のコマンドがゼロの終了ステータスを返す場合にのみコマンドを実行します (よくできました)

cd tmp/ && tar xvf ~/a.tar

別のコマンドがゼロ以外の終了ステータスを返した場合にのみコマンドを実行する (終了していない)

cd tmp/a/b/c ||mkdir -p tmp/a/b/c

read

ユーザー入力の読み取り

read input
echo $input

配列

配列の宣言

declare -a array=()

または

declare array=()

または

declare -A array=()

圧縮・解凍

tar.bz2 ファイルを解凍します (例: file.tar.bz2)。

tar xvfj file.tar.bz2

tar.xz ファイルを解凍します (例: file.tar.xz)。

unxz file.tar.xz
tar xopf file.tar

pdftotext

PDFをtxtに変換

sudo apt-get install poppler-utils
pdftotext example.pdf example.txt

書籍の紹介

MacOSをアップデートしてから、ターミナルを開くたびに、「The default interactive shell is now zsh.」というメッセージが表示されるようになりました。

MacOSをアップデートしてから、ターミナルを開くたびに、「The default interactive shell is now zsh.」というメッセージが表示されるようになりました。

【ターミナルTIPS】ターミナルで知っておくとちょっとだけ便利なコマンド

【ターミナルTIPS】ターミナルで知っておくとちょっとだけ便利なコマンド