coreutils
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]