Forum Archive

How to sort a text file by line length (ASC or DESC) ?

tguillemin

I have a file (Gradus.txt) with the following lines :

aaa
bb
cccc
d
eeeeee
fffff

and I would like to sort it (e.g. ASC) :

d
bb
aaa
cccc
fffff
eeeeee

How should I proceed ? (NB : my Python skills are not worth mentioning...)

Thanks in advance for your help

ccc
my_list = '''aaa
bb
cccc
d
eeeeee
fffff'''.splitlines()

#with open('Gradus.txt') as in_file:
#   my_list = in_file.readlines()

print('\n'.join(sorted(my_list)))
print('=' * 5)
print('\n'.join(sorted(my_list, key=len)))
print('=' * 5)
print('\n'.join(reversed(sorted(my_list, key=len))))
print('=' * 5)
tguillemin

First of all, thank you for your answer.

I did as you told me. Here is the Python script I incorporated in my workflow (I kept only the ASC sorting) :

#coding: utf-8

import sys

my_list = input

#print('\n'.join(sorted(my_list)))
#print('=' * 5)

print('\n'.join(sorted(my_list, key=len)))   #Line 10
print('=' * 5)

#print('\n'.join(reversed(sorted(my_list, key=len))))
#print('=' * 5)

But I get the following message :

Line 10: TypeError: 'builtin_function_or_method' object is not iterable

Did I do something wrong ?

Thanks again

dgelessus

input is a standard Python function. Because functions are normal objects in Python (unlike e. g. in Java) you can assign them to different names. The line my_list = input assigns the function named input to the name my_list. Now when you try to sort my_list, Python gives you an error, because a function is not something like a list that can be sorted.

In this case you were just unlucky that input is a predefined name in Python. If you try to use a name that doesn't exist (e. g. my_list = qwertyuiop) then Python will give you a NameError right away and tell you that there is no name qwertyuiop.

If you have a string of text (let's call it input_text) and you want to get a list of lines from the text, then you need to use my_list = input_text.splitlines() (like in @ccc's example above).

tguillemin

I think my problem is I do not understand how to name the input I receive from my workflow, which goes as follows (and I wish to be able to use it in any text I create, whatever its name) :

  • Extend selection (Direction : Both ; Unit : Start/End of Document)
  • Selected Text (Empty Selection Output : No output ; Folded Text Include)
  • Run Python script

How do I grab the Selected Text - and under what name ? - in my Python script ?

Thanks again

ccc

Sorry @tguillemin , I failed to see your question was in the Editorial section of the user forum...

http://omz-software.com/editorial/docs/ios_workflows/special/action-run-script.html and
http://omz-software.com/editorial/docs/ios/workflow.html explain that workflow.get_input() is your friend.

  • The first step of your workflow should be a Document Text action to get all the text of the current Editorial document.
  • The second step of your workflow should be a Run Python Script action with the following code in that step...
#coding: utf-8
import workflow

action_in = workflow.get_input()
my_list = action_in.splitlines()

print('\n'.join(my_list))
print('=' * 5)
print('\n'.join(sorted(my_list)))
print('=' * 5)
print('\n'.join(sorted(my_list, key=len)))
print('=' * 5)
print('\n'.join(reversed(sorted(my_list, key=len))))
print('=' * 5)

#: Generate the output...
action_out = '\n'.join(reversed(sorted(my_list, key=len)))
workflow.set_output(action_out)
tguillemin

@ccc Thank you very much. It works.

(NB : I am left in the Python console. Is there a way to be automatically brought back to my text ?)

Thanks again

ccc

If you don't want to end up on the console then don't print().

#coding: utf-8
import workflow
workflow.set_output('\n'.join(reversed(sorted(
    workflow.get_input().splitlines(), key=len))))
tguillemin

Thank you again !