bash(macos)를 사용하여 문자열이 포함된 줄의 일부 변경

bash(macos)를 사용하여 문자열이 포함된 줄의 일부 변경

음악 재생 목록 파일 .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

관련 정보