Estou escrevendo algo que lida com correspondências de arquivos e preciso de uma operação de inversão. Eu tenho uma lista de arquivos (por exemplo, find . -type f -print0 | sort -z >lst
) e uma lista de correspondências (por exemplo, grep -z foo lst >matches
- note que este é apenas um exemplo; matches
pode ser qualquer subconjunto arbitrário (incluindo vazio ou completo) ou lst
), e agora quero inverter essa lista.
Antecedentes: estou meio que implementando algo como encontrar (1) exceto listas de arquivos (embora os arquivos existam em o sistema de arquivos no ponto de chamada, a lista pode ter sido pré-filtrada). Se a lista de arquivos não fosse tão grande, eu poderia usar find "${files[@]}" -maxdepth 0 -somecondition -print0
, mas mesmo o uso moderado do que estou escrevendo ultrapassaria o limite de tamanho do Linux ou do BSD argv
.
Se as linhas não fossem separadas por NUL, eu poderia usar comm -23 lst matches >inverted
. Se as correspondências não fossem separadas por NUL, eu poderia usar grep -Fvxzf matches lst
. Mas, dos geradores que mencionei no primeiro parágrafo, ambos são.
Suponha que as ferramentas GNU estão instaladas, portanto, isso não precisa ser portável além de, por exemplo, Debian, como eu estou usando find -print0
, sort -z
e amigos já (embora alguns BSDs tenham, então se isso pode ser feito em "mais portável", eu não vou reclamar).
Estou tentando fazer a reutilização de código aqui; Além disso, comm -23
é basicamente a ferramenta perfeita para isso, exceto que ele não suporta a alteração do separador de linha de entrada (ainda), e comm é uma ferramenta subestimada e pouco conhecida. Se a caixa de ferramentas Unix / Linux não oferecer nada sensato, provavelmente reimplementarei uma forma de comm -23
(reduzida a apenas este caso de uso) no shell, já que o script (por outros motivos) requer um shell que Acontece para suportar read -d ''
para entrada delimitada por NUL, mas isso vai ser lento (e esforço ... eu postei isso no final do dia de trabalho na esperança de que alguém tenha uma idéia para quando eu pegar isso amanhã ou no dia 28 ).