6

bash でファイルを読み取り、リクエスト行を削除する必要がありますか? ポップ/プッシュ機能に似たものもあります。

どうすればできますか?

4

3 に答える 3

17

右!sed仕事をうまくやります!

はじめに

@Lee Nethertonからのコメントで正しく指摘されているように、インプレース編集のためにを実行する場合は、バックアップの使用を強くお勧めします! (もちろん、完了したら、スクリプトは続行する前にコマンドの成功をテストする必要があります...)sed

テストケース

それでは、テストファイルをすばやく作成しましょう。

printf "Line #%2d\n" {1..7} >file

ポップの場合(スタックの一番上から):

実際の push/popとして、次のコマンドは必要な行返し、指定されたファイルから削除します。

sed -e \$$'{w/dev/stdout\n;d}' -i~ file
Line # 7

それから

cat file
Line # 1
Line # 2
Line # 3
Line # 4
Line # 5
Line # 6

シフトの場合(スタックの一番下から):

sed -e 1$'{w/dev/stdout\n;d}' -i~ file
Line # 1

スプライス用(スタック内のランダム アクセス)

( n行目を削除)

lineNum=3
sed -e $lineNum$'{w/dev/stdout\n;d}' -i~ file
Line # 4

プッシュの場合(スタックの一番上へ):

printf -v val "Line #%2d" 28
echo "$val" >>file

sed注: これはとにかく次を使用して行うことができます。

sed -e "\$a$val" -i~ file

(ここで$a、変数ではなく、ファイルの末尾を意味するsedの場所と、現在の行の後に追加することを意味するコマンド)$a

unshiftの場合(スタックの一番下まで):

printf -v val "Line #%2d" 62
sed -e 1i"$val" -i~ file

そしたら最後に

cat file
Line #62
Line # 2
Line # 3
Line # 5
Line # 6
Line #28

変数に

もちろん、目標はそれらを変数に取得することです。を使用しているか、別のPOSIX を使用しているかに応じて、次のいずれかを使用できます。

lastline=`sed -e \\\$$'{w/dev/stdout\n;d}' -i~ file`
echo $lastline 
Line #28

lastline=$(sed -e \$$'{w/dev/stdout\n;d}' -i~ file)
echo $lastline 
Line # 6

read lastline < <(sed -e \$$'{w/dev/stdout\n;d}' -i~ file)
echo $lastline 
Line # 5

2018年新年に追加

明けましておめでとう!

簡単な bash 関数の例:

fpop() { local v n=$'\n';read -r v < <(
    sed -e $'${w/dev/stdout\n;d}' -i~ "$1")
    printf ${2+-v} $2 "%s${n[${2+2}]}" "$v"
}
fshift() { local v n=$'\n';read -r v < <(
    sed -e $'1{w/dev/stdout\n;d}' -i~ "$1")
    printf ${2+-v} $2 "%s${n[${2+2}]}" "$v"
}
fsplice() {
    [ "$2" ] || return ; local v n=$'\n';read -r v < <(
    sed -e $2$'{w/dev/stdout\n;d}' -i~ "$1");
    printf ${3+-v} $3 "%s${n[${3+3}]}" "$v"
}
fpush() { sed -e "\$a$2" -i~ "$1"; }
funshift() { sed -e "1i$2" -i~ "$1"; }

注: 行は、私が関数でよく使用printf ${2+-v} $2 "%s${n[${2+2}]}" "$v"する一種のトリックです。2 番目の引数として送信された場合、この行は変数を設定します。それ以外の場合、この行は改行を追加してに出力しますSTDOUT

少し実行サンプル:

printf "Line #%2d\n" {3..12} >file   

fpop file
Line #12
fpop file myvar
echo $myvar
Line #11

fshift file
Line # 3
fshift file myvar
echo $myvar
Line # 4

fsplice file 3 
Line # 7
fsplice file 3 myvar
echo $myvar
Line # 8

funshift file "Line # 192"
fpush file "Line # 42"

cat file
Line # 192
Line # 5
Line # 6
Line # 9
Line #10
Line # 42

declare -p myvar
declare -- myvar="Line # 8"

(変数myvarにはnewlineが含まれていませんでした。)

そして (私は抵抗できません! ;-):

fpop file myvar
echo $((9? ${myvar#*#} :-b))
42
于 2012-12-10T16:44:34.287 に答える
0

sed特定の行番号または特定のパターンに一致する行を削除するために使用できます。

$ cat file
line 1
line 2 
line 3 
line 4
line 5

$ sed -i '3d' file             # Delete the 3rd line
line 1
line 2 
line 4
line 5    

$ sed -i '/^line 4$/d' file    # Delete the line that matches the pattern
line 1
line 2 
line 3 
line 5


$ sed '$d' file                # Delete the last line in the file
line 1
line 2 
line 3 
line 4

ただし、これらの行に戻ることはできませんpush..

于 2012-12-10T16:33:19.020 に答える