
$ ls *
2000-01-01-abcd.md
2000-01-01-cdef.md
次のコマンドからabcdとcdefを抽出できます。
find *.md -exec sh -c "echo {} | sed 's/.md//' | sed 's/2000-01-01-//'" \;
ファイルの先頭に文字列を追加してこれを行う方法を知っていますが、sed '1s/^/string/'
正確な文字列を渡すにはどうすればよいですか?
各ファイルの先頭に対応する文字列を追加したいので、この文字列 "abcd"と "cdef"をそのファイルにどのように渡すことができますか?
答え1
各ファイルの先頭に対応する文字列を追加します。
強く打つ+sed方法:
for f in *.md; do fn=${f##*-}; sed -i "1 s/^/${fn%.*} /" "$f"; done
fn=${f##*-}
- 最も長い一致シーケンスを左から最後の項目に切り捨てます-
(例abcd.md
:)。${fn%.*}
.
- 前の部分文字列fn
(たとえば)がabcd
最初に表示されるまで、一番右のシーケンス(終わりから始まる)を切り捨てます。sed -i "1 s/^/${fn%.*} /" "$f"
- ファイルの先頭に希望の文字列を追加します。
答え2
私はこれが私が探していたものに最も近いことがわかりました。 tmpバッファのアイデアはこの目的を解決します。他の解決策はforループを提案しており、私の考えではfind -execの組み合わせはすでにこの問題を解決しています。
https://unix.stackexchange.com/a/197400/119007
find ./ -name '*.md' -exec sh -c "echo '{}' | sed 's/.md//' | sed 's/2000-01-01-//' > tmp && cat {} >> tmp && mv tmp {}" \;
答え3
*.md
コマンドでこれを引用する必要がありますfind
。それ以外の場合は、実行時に一致する名前に展開されます。また、{}
引用文の文脈で使用しないでください(例:「find -exec sh -c」を使っても安全ですか?)。
シェルループソリューションは次のとおりです。
for name in ./*.md; do
prefix="${name%.md}" # "./2000-01-01-abcd.md" --> "./2000-01-01-abcd"
prefix="${prefix##*-}" # "./2000-01-01-abcd" --> "abcd"
{ echo "$prefix"; cat "$name"; } >"$name".tmp && mv "$name".tmp "$name"
done
同じことfind
:
find . -type f -maxdepth 1 -name "*.md" \
-exec sh -c 'p="${1%.md}";p="${p##*-}";{ echo "$p";cat "$1"; }>"$1".tmp && mv "$1".tmp "$1"' sh {} ';'