1

I have a file with 2 characters in each line, like this:

RU    
8A   
1C

How can I read those characters into a unix command (in this case, forming an argument list for ls -t)? I want something like this:

ls -t RU* 8A* 1C*   
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    Piping `ls` commands to each other doesn't make any sense. `ls` doesn't read from stdin, so output from all but the last will just be ignored. – Charles Duffy Apr 04 '18 at 15:08
  • Assuming `ls` is just a placeholder, though -- do you want to change the number of pipeline elements based on the number of lines in the file? Is it intentional that the last line *isn't* used as a wildcard prefix? – Charles Duffy Apr 04 '18 at 15:09
  • the characters in the file are prefixes that i want to use in a ls - t command, the content in the file can differ from time to time, so i need the command to be dynamic – Sentes Snus Apr 04 '18 at 15:11
  • Again, your `ls -t` pipeline shown in the question *doesn't actually work*. It ignores all but the last line. If you want to show us what you want to do, show us something that works; we can't infer intent from broken code. – Charles Duffy Apr 04 '18 at 15:12
  • (Also, [parsing output of `ls`](http://mywiki.wooledge.org/ParsingLs) is generally error-prone; if you want to sort a bunch of files by date, there are better ways to do it). – Charles Duffy Apr 04 '18 at 15:13
  • It should be a ls -t command but with a filter on RU*, 8A* and so on – Sentes Snus Apr 04 '18 at 15:13
  • Three separate invocations of `ls -t`, sorted individually? One, sorted together? And, again, `ls -t` output should never be parsed -- it's tool that's adequately specified only for human consumption of output, since its handling of unusual filenames is implementation-defined. – Charles Duffy Apr 04 '18 at 15:15
  • Maybe `ls -t RU* ; ls -t 8A* ; ls -t 1C*` or `ls -t RU* 8A* 1C*` – Mark Setchell Apr 04 '18 at 15:16
  • Or it could be that they want `ls -t RU* 8A* 1C*`. We don't know, because the OP isn't telling us. – Charles Duffy Apr 04 '18 at 15:16
  • ls -t RU* 8A* 1C* tested it. This is exactly what i need, sry for responding so late – Sentes Snus Apr 04 '18 at 15:21
  • Note that `ls -t RU* 8A* 1C*` will fail if you give it more arguments than will fit on a single command line. (Where that limit is varies by operating system, and on the number and size of environment variables you have exported, which count against the same limit). – Charles Duffy Apr 04 '18 at 15:24

1 Answers1

1

If you want three separate runs of ls:

while IFS= read -r line; do
  ls -t "$line"*
done <input_file.txt

If you want just one run, with all the content globbed together:

set --
while IFS= read -r line; do
  [ -n "$line" ] || continue
  set -- "$@" "$line"*
done <input_file.txt
ls -t "$@"

Note that ls -t is an unreliable tool. It won't work if you pass it more filenames than can be given to a single command invocation (and attempts to make it work using xargs will give you multiple, individually-sorted lists in output). If on a platform with GNU tools (bash, and GNU find and sort), consider the following instead:

#!/usr/bin/env bash

predicates=( -false )
while IFS= read -r line; do
  predicates+=( -o -name "${line}*" )
done <input_file.txt

while IFS= read -r -d' ' mtime && IFS= read -r -d '' filename; do
  echo "Processing file $filename with timestamp $mtime"
done < <(find . -maxdepth 1 '(' "${predicates[@]}" ')' -printf '%T@ %P\0' | sort -z -n)

Useful links:

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Had a bug in the `find` version earlier -- I'd switched from populating `"$@"` to using an array named `predicates`, but wasn't expanding that array onto the `find` command line. See the recent edit. – Charles Duffy Apr 04 '18 at 15:33