음악 재생 목록 파일 .m3u에서 문자열 "[LD]"가 포함된 줄을 식별하고 해당 줄을 특정 변경 사항으로 업데이트해야 합니다.
예를 들어:
/music/Miles Davis/1959 - Kind of Blue [LD]/Miles Davis - So What.mp3
다음과 같아야 합니다.
/music/_lossless/Miles Davis/1959 - Kind of Blue/Miles Davis - So What.mp3
즉. "/music/"에 문자열 "_lossless/"가 삽입된 후 음악 파일 경로에서 문자열 "[LD]"가 삭제됩니다.
각 파일은 다른 많은 프로세스도 실행해야 하기 때문에 파일에 대해 for 루프를 사용합니다.
for f in *.m3u;
do
# I can identify the lines using:
fgrep -n "[LD]" "$f"
# I can grab the line number using:
ld_line=$(fgrep -c "[LD]" "$f")
# and have tried processing the changes using sed, but it is not working..
#sed "$ld_lines![LD]!!" "$f"
# Ive also tried using sed as follows:
sed '![LD]!s!music!music/_lossless!' "$f"
# but neither of the above approaches either work or handle both modifications
done
솔루션은 sed를 사용할 필요가 없습니다. 무엇이든 최선입니다.
답변1
sed '/ \[LD\]/ { s///; s,/,/_lossless/,2; }' file
하위 문자열이 포함된 파일의 행을 찾으려면 [LD]
에서 정규식을 사용할 수 있습니다. 정규식에서 갖는 특별한 의미를 잃으려면 이스케이프 처리해야 합니다. 탈출할 필요는 없지만 대칭을 위해 탈출할 것입니다./ \[LD\]/
sed
[
]
하위 문자열이 포함된 줄을 찾으면 [LD]
해당 문자열을 대체 문자열로 바꿀 수 있습니다. 즉, 삭제합니다 s///
. 빈 정규 표현식을 사용하면 일치하는 표현식인 가장 가까운 표현식이 재사용됩니다 [LD]
.
다음 대체는 두 번째 것을 /
string 으로 대체하는 것입니다 /_lossless/
. /
끝에 있는 것을 사용하여 해당 줄에서 정규 표현식과 일치하는 두 번째 항목을 선택하고 , 2
편의상 슬래시 대신 쉼표를 명령 구분 기호로 사용합니다.
루프에서 .new
파일 이름 접미사를 사용하여 파일을 만듭니다.
for name in *.m3u; do
sed '/ \[LD\]/ { s///; s,/,/_lossless/,2; }' -- "$name" >"$name".new
done
macOS에서 파일을 변경하려면 sed -i '' ...
.
for name in *.m3u; do
sed -i '' '/ \[LD\]/ { s///; s,/,/_lossless/,2; }' -- "$name"
done
파괴적인 명령을 테스트하기 전에 데이터를 백업하는 것을 잊지 마십시오.
답변2
당신은 이것을 시도 할 수 있습니다sed
for f in *.mp3; do
var1=$(sed -E 's|(.[^/]*)(.[^[]*).*](.*)|\1/_lossless\2\3|' "$f")
mv "$f" "var1"
done
산출
/music/_lossless/Miles Davis/1959 - Kind of Blue /Miles Davis - So What.mp3