ターゲットファイルにスペースが必要な場合は、バッチの名前変更

ターゲットファイルにスペースが必要な場合は、バッチの名前変更

タイトル名に基づいて任意の名前を使用してMarkdownファイルのバッチの名前を変更し、ターゲット名にスペースを含める必要があります(これは標準です)。私はこの1行を試しています

for i in *;
do mv $i $(grep \# $i | head -1 | sed 's/# //' | sed 's/[_\?\!\]//' | sed 's/[:/]/ - /') ; 
done

ただし、名前にスペースが含まれているため、「ターゲットXがディレクトリではありません」というエラーが発生します。

どのようなヒントがありますか?

ベストアンサー1

主な問題は、コマンド置換が引用されず、異なるパラメータに分割され、各パラメータはパス名拡張の対象となり(後者はありませんbashzshmv2つ以上が見える場合は次のように仮定します。最後はファイルを移動するディレクトリです。

同じ理由でそれ$i自体を引用し、bashダッシュで始まるいくつかのファイル名で発生する問題を回避するには、代わりにパターンに-inを使用するか、コマンドに閉じるマーカーオプションを入れる必要があります。./**--mv

また、ファイル名の処理方法を少し簡素化できると思います。まず、sed複数のコマンドを許可できるので、一度だけ呼び出すだけです。最初の一致だけでなく、すべての一致を置き換えるには、コマンドの/g最後に追加することもできます。s///また、バックスラッシュの3つのうち2つは[_\?\!\]重複します。[_?!]を一致させるか、バックスラッシュも含めたい場合(一部のユーティリティを使用するとより確実にすることができますが)を使用します_?![_\?!][_\\?!]

for f in ./*; do
    mv -- "$f" "$(grep \# "$f" | head -1 | sed -e 's/# //g' -e 's/[_?!]//g' -e's/[:/]/ - /g')"
done

また、次のようにとgrepを組み合わせることもできます。headsed

for f in ./*; do
    mv -- "$f" "$(sed -ne '/^# / {s///; s/[_?!]//g; s/[:/]/ - /g; p; q;}' < "$f")"
done

ここで、内部コマンドは{}パターンによって条件が適用され、/^# /最後qにスクリプトがブロックの最後で終了するため、一致する最初の行だけが処理されます。

またawk

awk '/^# / { sub(/# /, ""); gsub(/[_?!]/, ""); gsub(/[:/]/, " - "); print; exit }' < "$f"

また、最後の置換をに変更して、s/[:/] */ - /このような文字列が(ダッシュの後に2つのスペース)の代わりになるようにblah: blehすることもできます。blah - blahblah - bleh

おすすめ記事