Se o seu head suportar desvios negativos:
for file in *.xyz; do
if [ "$(tail -n 1 < "$file")" = END ]; then
head -n -1 < "$file" > "${file%.xyz}_s.xyz"
fi
done
(se isso não acontecer, substitua head -n -1 por sed '$d' ).
Você pode torná-lo mais eficiente com ksh93 :
for file in *.xyz; do
if IFS= read -r last4 < "$file" <#((EOF-4)) <#((here=CUR)) &&
[ "$last4" = END ]; then
command /opt/ast/bin/head -c "$here" < "$file" > "${file/%.xyz/_sfor file in *.xyz; do
if IFS= read -r last4 < "$file" <#((EOF-4)) &&
[ "$last4" = END ]; then
newfile=${file/%.xyz/_sfor file in *.xyz; do
if [ "$(tail -n 1 < "$file")" = END ]; then
head -n -1 < "$file" > "${file%.xyz}_s.xyz"
fi
done
}
cp --reflink=auto -- "$file" "$newfile" &&
: 1<>; "$newfile" >#((EOF-4))
fi
done
}"
fi
done
Como está apenas usando comandos incorporados.
Se o seu sistema de arquivos oferecer suporte a cópias de retrovisor (que copia arquivos em que os dados não são duplicados até serem modificados, o que economizaria tempo e espaço em disco), você ainda pode usar ksh93 e GNU cp :
for file in *.xyz; do
if IFS= read -r last4 < "$file" <#((EOF-4)) <#((here=CUR)) &&
[ "$last4" = END ]; then
command /opt/ast/bin/head -c "$here" < "$file" > "${file/%.xyz/_sfor file in *.xyz; do
if IFS= read -r last4 < "$file" <#((EOF-4)) &&
[ "$last4" = END ]; then
newfile=${file/%.xyz/_s%pre%}
cp --reflink=auto -- "$file" "$newfile" &&
: 1<>; "$newfile" >#((EOF-4))
fi
done
}"
fi
done
Ou seja, estamos fazendo uma cópia de reflink e truncando-a em 4 bytes do final.