
というファイルがあります共通.txt絶対パスのリストが含まれます。例:
/etc
/etc/group
/var/log/syslog
私もファイルセットを持っています<ホスト名>.txt絶対パスのリストも含まれています。以下は例です(ホスト1.txt):
/root/.bashrc
/var/log/syslog
/etc/hosts
/bin/true
/etc
/sbin/rtmon
/etc/group
表示されるすべてのパスを削除したい共通.txtファイルセット内のすべてのファイルから<ファイル名>.txt. サンプルファイルホスト1.txt上記は次のようになります:
/root/.bashrc
/etc/hosts
/bin/true
/sbin/rtmon
これを実行するために、次の Bash スクリプトを作成しました。
#!/bin/bash
set -o nounset
set -o errexit
set -o pipefail
while read -r ONE_PATH
do
for ONE_FILE in host1.txt host2.txt host3.txt
do
sed -i '\:'"$ONE_PATH"':d' "$ONE_FILE"
done
done < common.txt
sed コマンドを正しく実行するのに苦労しています。上記の結果では、操作されたすべてのファイルが空になります。
目標を達成するためにこれをどのように修正すればよいでしょうか?
答え1
#!/bin/bash
set -o nounset
set -o errexit
set -o pipefail
declare -r SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
declare -r FILES_DIR=${SCRIPT_DIR%/*}
while read -r ONE_PATH
do
for ONE_FILE in $(find "$FILES_DIR" -maxdepth 1 -type f -print)
do
if [[ "$ONE_FILE" == *".swp" ]] ||
[[ "$ONE_FILE" == *"common.txt" ]]; then
continue
fi
sed -i '\|^'"$ONE_PATH"'$|d' "$ONE_FILE"
done
echo "Done removing $ONE_PATH"
done < "$SCRIPT_DIR"/../common.txt
exit 0
答え2
sed を使用しない解決策を提案してもよろしいでしょうか?
sort common.txt > common.txt.sorted
for f in host1.txt host2.txt host3.txt ; do
sort $f > $f.sorted
diff common.txt.sorted $f.sorted | egrep '^>' | sed -e 's/^> //' > $f.output
rm $f.sorted
done
選別リストをアルファベット順に並べ替えます。 差分ファイルとの違いを見つけます共通.txt。egrepで始まる行>
、つまりホスト1.txt.ソート済みしかし、common.txt.ソート済み。 ついに、sed先頭>
の(スペースが続く)>を削除します差分。
出力リストもアルファベット順になります。
答え3
まず、入力を逆順にソートする必要があります。/etc を削除してから /etc/group を探すのは無駄です。次に、ファイルに書き込み可能かどうかを確認します (書き込みできない場合はスキップします)。次に、ONE_PATH をエスケープして、sed が機能できるようにします。
sort -r common.txt \
| while read -r ONE_PATH
do
for ONE_FILE in host1.txt host2.txt host3.txt
do
if [ -w "$ONE_FILE" ]
then
# sed -i '\:'"$ONE_PATH"':d' "$ONE_FILE"
ONE_PATH_ESC=$(echo "$ONE_PATH" | sed "s!/!\\\/!g")
sed -i 's/^'"$ONE_PATH_ESC"'//' "$ONE_FILE"
fi
done
done
提供されたテスト データを使用すると、次のものが得られます。
$ pr -n host1.txt
1 /root/.bashrc
2
3 /hosts
4 /bin/true
5
6 /sbin/rtmon
7
空行が3行あります。