[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: RFE: head,tail: -z, --zero-terminated
From: |
Aaron Davies |
Subject: |
Re: RFE: head,tail: -z, --zero-terminated |
Date: |
Mon, 19 Oct 2015 22:47:24 -0400 |
On Sep 28, 2015, at 10:17 AM, Stephane Chazelas <address@hidden> wrote:
> 2015-09-26 15:43:40 +0100, Richard Russon:
>
>> I'd like to add an option to both head and tail,
>> to allow them to work with NUL-terminated lines of text
>> -z, --zero-terminated
>>
>> Thus allowing:
>>
>> find dir -type f -print0 | head -z -n 10 | xargs -0 command
>
> [...]
>
> See also
>
> sed -z 10q
>
> as an alternative to
>
> head -zn 10
>
> While we're at it, why not add it to every text utility (cut,
> paste, seq, yes, tac...) for those that don't have it already?
i second the motion
here's an example of something i had to do a few months back: given a
collection of directories, find the most-recently modified file in each
directory and pass the list of those files to some utility as command-line
arguments
here's the best i could come up with using mostly the standard shell tools
while still properly supporting fully-arbitrary filenames (i don't think the
sed on the system i was working on at the time includes the -z option)
(note the scripting uses some non-bourne features (arrays and function-local
variables))
the directories are a, b, and c; the utility is foo
function lastl { local r; while IFS= read -rd '' x; do r=$x; done; printf '%s'
"$r"; }
unset files
typeset -a files
dirs=(a b c)
while IFS= read -rd '' line
do
files["${#files[@]}"]=$line
done < <(
for dir in "${dirs[@]}"
do
find "$dir" -type f -printf '%T@\t%p\0' | sort -zk1,1n | lastl | perl
-0777ne 'printf("%s\0",$_)' | while IFS= read -rd '' l
do
tok0="${l%%$'\t*'}"
printf '%s\0' "${l:$((${#tok0}+1))}"
done
done
)
foo "${files[@]}"
my ideal would be something like the following; it requires giving -z options
to cut and tail (and head) and also creating a shortcut for the options that
make bash's `read' handle null-terminated text:
# ideal hypothetical code
unset files
typeset -a files
dirs=(a b c)
while read -z line
do
files["${#files[@]}"]=$line
done < <(for dir in "${dirs[@]}"; do find "$dir" -type f -printf '%T@\t%p\0' |
sort -zk1,1n | tail -zn1 | cut -z -d $'\t' -f 2; done)
foo "${files[@]}"
--
Aaron Davies
address@hidden
- Re: RFE: head,tail: -z, --zero-terminated,
Aaron Davies <=