1

So I'm deleting some files using find with regex's and then piping to xargs -0 rm or simply adding --delete

Occasionally, I need to exclude some of them from the removal - I write the find output to file, delete some lines and replace the new line characters with null characters. I do this in vim and now I have this EOF character that is causing me an annoyance, when I feed it to the remove command. Here's a very simplified test case using file instead of rm:

[testdir]$ touch t{1..3}
[testdir]$ find . -name 't*' -print0 > xa
[testdir]$ find . -name 't*' > xb
[testdir]$ cat -v xa
./t3^@./t2^@./t1^@[testdir]$ cat xb
./t3
./t2
./t1
[testdir]$ vim xb

In vim I do ':%s/\n/CTRL-@/' and save. Afterwards, the undesired effect, compared to the original find output file:

[testdir]$ cat -v xb
./t3^@./t2^@./t1^@
[testdir]$ xargs -a xa -0 file
./t3: empty
./t2: empty
./t1: empty
[testdir]$ xargs -a xb -0 -E '\012' file
xargs: warning: the -E option has no effect if -0 or -d is used.

./t3: empty
./t2: empty
./t1: empty

:    cannot open `\012' (No such file or directory)

rm works fine with all the files, it's just that I get an error at the end. Notice how the original output doesn't insert new line at the end, see result from 'cat xa'. Also, xargs tells me that I cannot exclude that EOF character, because of the null delimeter.

I'd love to know to know how to fix this, any ideas?

pidak
  • 23
  • 4
  • Well, remove the newline that is left in the input file. `how to fix this` fix what exactly? All utilities work as intended. What is that you want to achieve? Maybe instead of `-E $'\n'` just remove from the input everything from the newline using another utility.. but that questions, why do you use `vim` in the first place. – KamilCuk May 06 '20 at 21:38
  • That is my problem, it doen't seem to be a new line. It's end of file character I'm guessing. Also, if it were a new line, the substitution would have taken care of it. – pidak May 06 '20 at 21:42
  • 2
    `end of file character` there is no such thing. `EOF` is not a character. `the substitution would have taken care of it` - no, `vim` explicitly forces a trailing newline in files. ex. [disable automatic newline in vim](https://stackoverflow.com/questions/1050640/vim-disable-automatic-newline-at-end-of-file) or just remove the trailing newline... So your input file `xb` has `./t3./t2./t1` - when you separate it using zero you have 4 files - `./t3` `./t2` `./t1` __and__ ``, because you do not have a file named just newline, there is no such file or directory. – KamilCuk May 06 '20 at 21:42
  • 1
    Side note: I believe it would be typical to use `tr '\n' '\0'` – KamilCuk May 06 '20 at 21:46

1 Answers1

0

New day - new perspective! I slept on it, and thanks to KamilCuk's comments it is all clear now. First of all, as he stated, there is no such thing as end of file character. It is just a trailing new line '\n'.

As he suggested a way to go about removing this trailing new line is:

[testdir]$ cat xb | tr -d '\n'
./t3./t2./t1[testdir]$ 

Alternatively, for this specific case, this works too:

[testdir]$ cat xb | tr -d '\012'
./t3./t2./t1[testdir]$ 

Then I was thinking about the case, where I want just this one trailing new line of the file to be removed, without worrying about what happens with all the rest new line characters, if any were present. This is my suggestion for the case:

[testdir]$ head -c -1 xb
./t3./t2./t1[testdir]$ 

Now my file can be safely delimited by xargs -0 and Voilà!

pidak
  • 23
  • 4